/*
 * @Author: early-autumn
 * @Date: 2020-05-09 12:36:20
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2020-07-04 11:44:23
 */
/**
 * 列表数据转联级选择器数据
 * @param {Array<Object>} list
 * @param {Function} func
 */
export function listToTreeOptions(list, func = (i) => i) {
  const cache = {}
  const options = []
  const missing = {}
  list.forEach((item) => {
    const { parentId, id, label, value } = func(item)
    const parent = cache[parentId]
    const children = {
      label,
      value,
    }
    cache[id] = children
    if (parentId === 0) {
      options.push(children)
    } else if (parent) {
      parent.children = parent.children || []
      parent.children.push(children)
    } else {
      missing[parentId] = missing[parentId] || []
      missing[parentId].push(children)
    }
  })
  // 兜底
  Object.entries(missing).forEach(([parentId, children]) => {
    const parent = cache[parentId]
    if (parent) {
      parent.children = parent.children || []
      parent.children.push(...children)
    }
  })
  return options
}

/**
 * 编码
 * @param {Object} obj 对象
 */
export function encode(obj) {
  return encodeURIComponent(JSON.stringify(obj))
}

/**
 * 解码
 * @param {String} str 对象
 */
export function decode(str) {
  return JSON.parse(decodeURIComponent(str))
}

/**
 * 空对象
 * @param {Object} obj 需判断的值
 */
export function isEmptyObject(obj) {
  return Object.keys(obj).length === 0
}

/**
 * 选项转枚举
 * @param {Array<Object>} options
 * @returns {Object}
 */
export function optionsToEnum(options) {
  const Enum = {}
  options.forEach(({ label, value }) => {
    Enum[(Enum[label] = value)] = label
  })
  return Enum
}

/**
 * 深拷贝
 * @param {Object} obj
 * @returns {String}
 */
export function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj))
}

/**
 * 函数防抖
 *
 * @param {Function} func 需要防抖的函数
 * @param {Number} duration 持续时间
 * @returns {Function} packaging 包装后的函数
 */
export function debounce(func, duration = 300) {
  let timer = null
  return function packaging(...arg) {
    if (timer != null) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => func.apply(this, arg), duration)
  }
}

/**
 * 组合函数 从后往前依次调用
 *
 * @param func 函数集
 * @returns {*|(function(...[*]): *)}
 */
export function compose(...func) {
  return func.reduce((a, b) => (...arg) => a(b(...arg)))
}

/**
 * 延时
 * @param time
 * @returns {Promise<unknown>}
 */
export function delay(time) {
  return new Promise((resolve) => setTimeout(resolve, time))
}
